package cn.wx.common.persistence.config.mybatis;

import com.baomidou.mybatisplus.MybatisConfiguration;
import com.baomidou.mybatisplus.MybatisXMLLanguageDriver;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.enums.DBType;
import com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;

import cn.wx.common.persistence.exception.MyException;
import cn.wx.common.persistence.web.ResponseCode;

import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.sql.DataSource;

/**
 *   @description : myatis-plus 配置类
 *   ---------------------------------
 *   @author zj
 *   @since 2017-10-27
 */
@Configuration
@EnableConfigurationProperties(MybatisProperties.class)
public class MybatisPlusConfig {

    @Autowired
    private DataSource dataSource;
    
    @Autowired
    private MybatisProperties properties;
    
    @Autowired
    private ResourceLoader resourceLoader = new DefaultResourceLoader();
    
    @Autowired(required = false)
    private Interceptor[] interceptors;
    
    @Autowired(required = false)
    private DatabaseIdProvider databaseIdProvider;
    
    @Value("${pagination.dialectType}")
    private String dialectType;
    
    @Value("${mybatis.plus.dbType}")
    private String dbType;
    
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
    	return new OptimisticLockerInterceptor();
    }
    
    /**
     * @Description : mybatis-plus SQL执行效率插件【生产环境可以关闭】
     * ---------------------------------
     */
    @Bean
    public PerformanceInterceptor performanceInterceptor() {
    	PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
    	performanceInterceptor.setFormat(true);// SQL是否格式化 默认false
    	performanceInterceptor.setMaxTime(30000);// maxTime 指的是 sql 最大执行时长
        return performanceInterceptor;
    }

    /**
     * mybatis-plus分页插件<br>
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
    	PaginationInterceptor page = new PaginationInterceptor();
        page.setDialectType(dialectType);//"sqlserver" mysql
        page.setLocalPage(true);// 开启 PageHelper 的支持
        return page;
    }
    
    @Bean
    public MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean() {
    	
        MybatisSqlSessionFactoryBean mybatisPlus = new MybatisSqlSessionFactoryBean();
        
        mybatisPlus.setDataSource(dataSource);
        mybatisPlus.setVfs(SpringBootVFS.class);
        
        if (StringUtils.hasText(this.properties.getConfigLocation())) {
            mybatisPlus.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
        }
        mybatisPlus.setConfiguration(properties.getConfiguration());
        
        if (!ObjectUtils.isEmpty(this.interceptors)) {
            mybatisPlus.setPlugins(this.interceptors);
        }
        // MP 全局配置，更多内容进入类看注释
        GlobalConfiguration globalConfig = new GlobalConfiguration();

        switch (dbType) {
		case "mysql": globalConfig.setDbType(DBType.MYSQL.name()); break;
		case "sqlserver2005": globalConfig.setDbType(DBType.SQLSERVER2005.name()); break;
		case "sqlserver": globalConfig.setDbType(DBType.SQLSERVER.name()); break;
		default:
			throw new MyException(ResponseCode.DBTYPE_NOTEXIT);
		}
        globalConfig.setDbType(DBType.MYSQL.name());
        
        // ID 策略 AUTO->`0`("数据库ID自增") INPUT->`1`(用户输入ID") ID_WORKER->`2`("全局唯一ID") UUID->`3`("全局唯一ID")
        globalConfig.setIdType(0);
        // 全局下划线转驼峰
        globalConfig.setDbColumnUnderline(false);
        
        // 字段策略
        globalConfig.setFieldStrategy(1);
        
        mybatisPlus.setGlobalConfig(globalConfig);
        MybatisConfiguration mc = new MybatisConfiguration();
        mc.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
        mc.setJdbcTypeForNull(JdbcType.NULL);// 插入空值时设定
        mc.setMapUnderscoreToCamelCase(false);// 开启下划线转驼峰
        //mc.setObjectWrapperFactory(new MybatisMapWrapperFactory());//*注册Map 下划线转驼峰*
        mc.setCacheEnabled(false);
        mybatisPlus.setConfiguration(mc);
        
        if (this.databaseIdProvider != null) {
            mybatisPlus.setDatabaseIdProvider(this.databaseIdProvider);
        }
        if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
            mybatisPlus.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
        }
        if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
            mybatisPlus.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
        }
        if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
            mybatisPlus.setMapperLocations(this.properties.resolveMapperLocations());
        }
        return mybatisPlus;
    }

}